package com.gb.web.common.utils;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;

/**
 * http工具类
 */
public class RequestUtil  extends org.springframework.web.util.WebUtils{
	
	
	public static HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	public static HttpSession getSession() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
	}

	public static HttpServletResponse getResponse() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
	}

	public static ServletContext getContext() {
		return ContextLoader.getCurrentWebApplicationContext().getServletContext();
	}
	/**
	 * 获取application
	 * @return
	 */
	protected ServletContext getApplication() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().getServletContext();
	}

	 /**
     * 获取项目名称路径
     */
	public static String getContentpath() {
		return getRequest().getContextPath();
	}
     
	/**
	 * 获取项目绝对路径
	 */
	public static String getRealPath() {
		return getRequest().getSession().getServletContext().getRealPath("/");
	}
    

	/**
	 * @Description: getString() 获取k -v 的v
	 */
	public String getString(String name, String defaultValue) {
		String resultStr = getRequest().getParameter(name);
		if (resultStr == null || "".equals(resultStr) || "null".equals(resultStr) || "undefined".equals(resultStr)) {
			return defaultValue;
		} else {
			return resultStr;
		}
	}
	
	public static void setAttribute(String key, Object value) {
		getRequest().setAttribute(key, value);
	}
	
	public Object getSession(String key){
        return getRequest().getSession().getAttribute(key);
    }
    public void setSession(String key,Object val){
        getRequest().getSession().setAttribute(key,val);
    }
	
	
	public static String getDomain(HttpServletRequest request){
		return request.getServerName();
	}
	
	public static String getHttpDomain(HttpServletRequest request){
		return request.getScheme() + "://" + request.getServerName();
	}
	
	public static String getContextHttpUri(HttpServletRequest request){
		return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
	}
	
	public static String getRealPath(HttpServletRequest request){
		return request.getSession().getServletContext().getRealPath("/");
	}
	
	/**
     * 获取所有request请求参数key-value
     * @param request
     * @return
     */
    public static Map<String, String> getRequestParams(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        if (null != request) {
            Set<String> paramsKey = request.getParameterMap().keySet();
            for (String key : paramsKey) {
                params.put(key, request.getParameter(key));
            }
        }
        return params;
    }
	
	/**
	 * 获得请求参数值
	 */
	public static String getParameter(String name) {
		HttpServletRequest request = getRequest();
		if (request == null){
			return null;
		}
		return request.getParameter(name);
	}
	
	/**
	 * 支持AJAX的页面跳转
	 */
	public static void redirectUrls(HttpServletRequest request, HttpServletResponse response, String url){
		try {
			if (isAjaxRequest(request)){
				request.getRequestDispatcher(url).forward(request, response); // AJAX不支持Redirect改用Forward
			}else{
				response.sendRedirect(request.getContextPath() + url);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static String getRequestFullUri(HttpServletRequest request){
		String port = "";
		if(request.getServerPort() != 80){
			port = ":" + request.getServerPort();
		}
		return request.getScheme() + "://" + request.getServerName() + port + request.getContextPath() + request.getServletPath();
	}
	
	public static String getRequestFullUriNoContextPath(HttpServletRequest request){
		String port = "";
		if(request.getServerPort() != 80){
			port = ":" + request.getServerPort();
		}
		return request.getScheme() + "://" + request.getServerName() + port + request.getServletPath();
	}
	
    /**
	 * 获取当前域名路径
	 * @param request
	 * @return
	 */
	public static String getBasePath() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
		return basePath;
	}
	
    
    /**
     * 获取请求basePath
     */
    public static String getBasePath(HttpServletRequest request) {
        StringBuffer basePath = new StringBuffer();
        String scheme = request.getScheme();
        String domain = request.getServerName();
        int port = request.getServerPort();
        basePath.append(scheme);
        basePath.append("://");
        basePath.append(domain);
        if ("http".equalsIgnoreCase(scheme) && 80 != port) {
            basePath.append(":").append(String.valueOf(port));
        } else if ("https".equalsIgnoreCase(scheme) && port != 443) {
            basePath.append(":").append(String.valueOf(port));
        }
        return basePath.toString();
    }

	 public static void dispatcherUrl(HttpServletRequest request, HttpServletResponse response, String url){
		try {
			request.getRequestDispatcher(url).forward(request, response);
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	 }
	
	/**
	 * 重定向
	 * @param request
	 * @param response
	 * @param url
	 */
	public static void redirectUrl(HttpServletRequest request, HttpServletResponse response, String url){
		try {
			response.sendRedirect(request.getContextPath() + url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 重定向到http://的url
	 * @param request
	 * @param response
	 * @param url
	 */
	public static void redirectHttpUrl(HttpServletRequest request, HttpServletResponse response, String url){
		try {
			response.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//获取ip地址；
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
			if(ip.indexOf("::ffff:")!=-1) ip = ip.replace("::ffff:", "");
			int index = ip.indexOf(",");
			if (index != -1) {
				return ip.substring(0, index);
			} else {
				return ip;
			}
		}
		ip = request.getHeader("X-Real-IP");
		if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
			return ip;
		}
		return request.getRemoteAddr();
	}
	
	//判断当前请求是否为Ajax
	public static boolean isAjaxRequest(HttpServletRequest request) {
		String header = request.getHeader("X-Requested-With");
		return !StringUtils.isEmpty(header) && "XMLHttpRequest".equals(header);
	}
	
	public void outStr(HttpServletResponse response, String content) {
        //logger.info("交易响应结果=>" + content);
        outStr(response, content, true);
    }

	public void outStr(HttpServletResponse response, String content, boolean hasHeader) {
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            if (hasHeader) {
                response.setHeader("content-type", "text/html;charset=UTF-8");
            }
            byte[] dataByteArr = content.getBytes("UTF-8");
            outputStream.write(dataByteArr);
        } catch (Exception e) {
            //logger.error("outStr error", e);
        } finally {
            try {
                if (null != outputStream) {
                    outputStream.flush();
                    outputStream.close();
                }
            } catch (Exception e2) {
                //logger.error("outStr close stream error", e2);
            }
        }
    }
	
    /**
	 * 客户端返回JSON字符串
	 * @param response
	 * @param object
	 * @return
	 */
	protected String renderString(HttpServletResponse response, Object object) {
		return renderString(response, JSON.toJSONString(object), "application/json");
	}
	
	/**
	 * 客户端返回字符串
	 * @param response
	 * @param string
	 * @return
	 */
	protected String renderString(HttpServletResponse response, String string, String type) {
		try {
			response.reset();
	        response.setContentType(type);
	        response.setCharacterEncoding("utf-8");
			response.getWriter().print(string);
			return null;
		} catch (IOException e) {
			return null;
		}
	}
    
    /**
	 * 页面输出
	 * @param response
	 * @param o
	 */
	public static void write(HttpServletResponse response,Object o){
		try {
			//response.setContentType("text/html;charset=utf-8");
			response.setContentType("application/json");
			PrintWriter out=response.getWriter();
			out.println(o.toString());
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 发送内容。使用UTF-8编码。
	 * @param response
	 * @param contentType
	 * @param text
	 */
	public static void render(HttpServletResponse response, String contentType,String text) {
		response.setContentType(contentType);
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		try {
			response.getWriter().write(text);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
    
    /**
	 * 除去数组中的空值和签名参数
	 * @param sArray签名参数组
	 * @return 去掉空值与签名参数后的新签名参数组
	 */
	public static Map<String, String> paraFilter(Map<String, String> sArray) {
		Map<String, String> result = new HashMap<String, String>();
		if (sArray == null || sArray.size() <= 0) {
			return result;
		}
		for (String key : sArray.keySet()) {
			String value = sArray.get(key);
			if (value == null || value.equals("") || key.equalsIgnoreCase("signature")) {
				continue;
			}
			result.put(key, value);
		}
		return result;
	}

   /**
    * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
    * @param params 需要排序并参与字符拼接的参数组
    * @return 拼接后字符串
    */
   public static String createLinkString(Map<String, String> params){
       List<String> keys = new ArrayList<String>(params.keySet());
       Collections.sort(keys);
       String prestr = "";
       for (int i = 0; i < keys.size(); i++){
           String key = keys.get(i);
           String value = params.get(key);
           if (i == keys.size() - 1){ // 拼接时，不包括最后一个&字符
               prestr = prestr + key + "=" + value;
           }else{
               prestr = prestr + key + "=" + value + "&";
           }
       }
       return prestr;
   }
   
   /**
	 * 将URL 形式的字符串 <br>
	 * (a=b&c=d) 形式的字符串 转换成键值对形式的MAP
	 */
	public static Map<String, String> toQueryMap(String paramStr) {
		String[] vals = split(paramStr,"&");
		Map<String, String> resultMap = new HashMap<String, String>(vals.length);
		int index;
		for (int i = 0; i < vals.length; i++) {
			index = vals[i].indexOf("=");
			resultMap.put(vals[i].substring(0, index), vals[i].substring(
					index + 1, vals[i].length()));
		}
		return resultMap;
	}
	
	public static String toQueryString(Map<String, String>queryMap){
		StringBuilder builder = new StringBuilder();
		for (Map.Entry<String, String> item : queryMap.entrySet()) {
			builder.append(item.getKey()).append('=').append(item.getValue()).append('&');	
		}
		if(builder.length()>0){
			builder.setLength(builder.length()-1);
		}
		return builder.toString();
	}
	
	/**
	 * 将字符串转换成 String[] 数组<br> 支持复杂分隔符
	* @param msg 需要被截取的信息
	* @param cut 分隔符
	 */
	public static String[] split(String msg,String cut){
		int index = 0;
		int befault = 0;
		List<String>l = new ArrayList<String>(128);
		do{
			index = msg.indexOf(cut,index);
			l.add(msg.substring(befault, index == -1 ? msg.length() :index ));
			index+=1;
			befault = index+cut.length()-1;
		}while(index >0 && index < msg.length());
		return  l.toArray(new String[l.size()]);
	}
	
	 /**
     * 移除request指定参数
     */
    public String removeParam(HttpServletRequest request, String paramName) {
        String queryString = "";
        Enumeration keys = request.getParameterNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            if (key.equals(paramName)) {
                continue;
            }
            if ("".equals(queryString)) {
                queryString = key + "=" + request.getParameter(key);
            } else {
                queryString += "&" + key + "=" + request.getParameter(key);
            }
        }
        return queryString;
    }
    
    /**
     * 请求中参数转Map<String, String>,for支付宝异步回调,平时建议直接使用request.getParameterMap(),返回Map<String, String[]>
     */
    public static Map<String, String> getParameterMap(HttpServletRequest request) {
        Map<String, String> result = new HashMap<>();
        Enumeration parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = (String) parameterNames.nextElement();
            result.put(parameterName, request.getParameter(parameterName));
        }
        return result;
    }
}
